<template>
    <div>
        <el-form label-width="100px">
            <el-form-item label="SPU名称">
                <el-input placeholder="请你输入SPU名称" v-model="SpuParams.spuName"></el-input>
            </el-form-item>
            <el-form-item label="SPU品牌">
                <el-select placeholder="请你选择品牌" style="width: 300px;" v-model="SpuParams.tmId">
                    <el-option v-for="(item, index) in AllTradeMark" :key="item.id" :label="item.tmName"
                        :value="item.id" />
                </el-select>
            </el-form-item>
            <el-form-item label="SPU描述">
                <el-input type="textarea" placeholder="请你输入描述" v-model="SpuParams.description" />
            </el-form-item>
            <!-- v-model:fileList->展示默认图片 
                 action:上传图片的接口地址
                 list-type:文件列表的类型
            -->
            <el-form-item label="SPU图标">
                <el-upload v-model:file-list="imgList" action="/api/admin/product/fileUpload" list-type="picture-card"
                    :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :before-upload="handlerUpliad">
                    <el-icon>
                        <Plus />
                    </el-icon>
                </el-upload>

                <el-dialog v-model="dialogVisible">
                    <img w-full :src="dialogImageUrl" alt="Preview Image" style="width: 100%; height: 100%;" />
                </el-dialog>
            </el-form-item>
            <el-form-item label="SPU销售属性" size="normal">
                <el-select v-model="saleAttrIdAndValueName"
                    :placeholder="unSelectSaleAttr.length ? `还有${unSelectSaleAttr.length}未选择` : `无`"
                    style="width: 300px;">
                    <el-option :value="`${item.id}:${item.name}`" v-for="(item, index) in unSelectSaleAttr"
                        :key="item.id" :label="item.name" />
                </el-select>
                <el-button :disabled="saleAttrIdAndValueName ? false : true" type="primary" size="default"
                    @click="addSaleAttr" icon="Plus" style="margin:0px 10px;">添加销售属性</el-button>
                <el-table border stripe style="margin: 10px 0px;" :data="saleAttr">
                    <el-table-column label="序号" type="index" align="center" width="80px">
                    </el-table-column>
                    <el-table-column label="属性名" prop="saleAttrName" </el-table-column>
                        <el-table-column label="属性值">
                            <!-- row:即为当前SPU已有的销售属性对象 -->
                            <template #="{ row, $index }">
                                <el-tag v-for="(item, index) in row.spuSaleAttrValueList" :key="row.id"
                                    style="margin:0px 5px;" closable :disable-transitions="false"
                                    @close="row.spuSaleAttrValueList.splice(index, 1)">
                                    {{ item.saleAttrValueName }}
                                </el-tag>
                                <el-input v-model="row.saleAttrValue" v-if="row.flag" ref="InputRef" class="w-20"
                                    size="small" @blur="toLook(row)" style="width: 100px;" />
                                <el-button v-else type="primary" class="button-new-tag" size="small" icon="Plus"
                                    @click="toEdit(row)">
                                </el-button>

                            </template>
                        </el-table-column>
                        <el-table-column label="操作" width="120px">
                            <template #="{ row, $index }">
                                <el-button type="primary" size="small" @click="saleAttr.splice($index, 1)"
                                    icon="Delete"></el-button>
                            </template>
                        </el-table-column>
                </el-table>


            </el-form-item>
            <el-form-item>
                <el-button type="primary" size="default" @click="save"
                    :disabled="saleAttr.length > 0 ? false : true">保存</el-button>
                <el-button type="primary" size="default" @click="cancel">取消</el-button>
            </el-form-item>

        </el-form>

    </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import type { SpuData, AllTradeMark, SpuHasImg, SaleAttrResponseData, HasSaleAttrResponseData, Trademark, SpuImg, SaleAttr, HasSaleAtt, SaleAttrValue } from '@/api/product/spu/type';
import { reqAllTradeMark, reqSpuImageList, reqSpuHasSaleAttr, reqAllSaleAttr, reqAddOrUpdateSpu } from '@/api/product/spu';
import { ElMessage } from 'element-plus';
// 触发父组件changeScene方法
let $emit = defineEmits(['changeScene']);
// 取消按钮绑定的回调函数
const cancel = () => {
    $emit('changeScene',  { flag: 0, params: 'update' });//触发自定义事件，传递参数0
}
// 存储已有的SPU数据
let AllTradeMark = ref<Trademark[]>([]);
// 商品图片
let imgList = ref<SpuImg[]>([]);
// 商品销售属性
let saleAttr = ref<SaleAttr[]>([]);
// 所有销售属性
let allSaleAttr = ref<HasSaleAtt[]>([]);
// 控制对话框的显示和隐藏
let dialogVisible = ref<boolean>(false);
// 存储预览图片的地址
let dialogImageUrl = ref<string>('');
// 存储已有的spu对象
let SpuParams = ref<SpuData>({
    spuName: '',
    category3Id: '',
    tmId: '',
    description: '',
    spuImageList: [],
    spuSaleAttrList: []
})
// 收集还未选择的销售属性的ID和属性值名称
let saleAttrIdAndValueName = ref<string>('');

const handlePictureCardPreview = (fiel: any) => {
    // 显示对话框
    dialogImageUrl.value = fiel.url;
    dialogVisible.value = true;

}
// 移除图片
const handleRemove = () => {

}
// 约束上传图片
const handlerUpliad = (file: any) => {
    if (file.type == 'image/png' || file.type == 'image/jpeg' || file.type == 'image/gif') {
        if (file.size / 1024 / 1024 < 3) {
            return true
        } else {
            ElMessage({
                type: 'error',
                message: '上传文件务必小于3M'
            })
            return false
        }
    } else {
        ElMessage({
            type: 'error',
            message: '上传文件格式务必为PNG|JPG|GIF'
        })
        return false
    }
}
//子组件书写一个方法
const initHasSpuData = async (spu: SpuData) => {
    // 接收spu（不完整的数据），然后发送四个请求
    SpuParams.value = spu;
    // 获取全部品牌的数据
    let result: AllTradeMark = await reqAllTradeMark();
    // 获取某一个品牌的全部图片
    let result1: SpuHasImg = await reqSpuImageList((spu.id as number));
    // 获取已有spu销售属性的数组
    let result2: SaleAttrResponseData = await reqSpuHasSaleAttr((spu.id as number))
    // 获取整个项目全部SPU的销售属性
    let result3: HasSaleAttrResponseData = await reqAllSaleAttr();
    // 存储全部品牌的数据
    AllTradeMark.value = result.data;
    // spu对应的商品图片
    imgList.value = result1.data.map(item => {
        return {
            name: item.imgName,
            url: item.imgUrl
        }
    });
    // 商品销售属性
    saleAttr.value = result2.data;
    // 所有销售属性
    allSaleAttr.value = result3.data;
}
const initAddSpu = async (c3id: number | string) => {
    // 清空数据数据
    // 清空对象
    Object.assign(SpuParams.value, {
        spuName: '',
        category3Id: '',
        tmId: '',
        description: '',
        spuImageList: [],
        spuSaleAttrList: []
    })
    // 清空数组
    imgList.value=[];
    saleAttr.value=[];
    saleAttrIdAndValueName.value='';
    SpuParams.value.category3Id = c3id;
    let result = await reqAllTradeMark();
    let result1 = await reqAllSaleAttr();
    AllTradeMark.value = result.data;
    allSaleAttr.value = result1.data;

}
// 计算出Spu还没有拥有的属性
let unSelectSaleAttr = computed(() => {
    let unSelectArr = allSaleAttr.value.filter(item => {
        return saleAttr.value.every(item1 => {
            return item.name != item1.saleAttrName;
        })
    })
    return unSelectArr;
})
// 添加属性按钮的回调函数
const addSaleAttr = () => {
    const [baseSaleAttrId, saleAttrName] = saleAttrIdAndValueName.value.split(':');
    // 准备一个新的的销售属性对象：将来带给服务器即可
    let newSaleAttr: SaleAttr = {
        baseSaleAttrId,
        saleAttrName,
        spuSaleAttrValueList: []
    }
    // 追加到数组当中
    saleAttr.value.push(newSaleAttr);
    // 清空收集的数据
    saleAttrIdAndValueName.value = '';
}
// 改变输入框状态的函数
const toEdit = (row: SaleAttr) => {
    row.flag = true;
    row.saleAttrValue = '';//收集属性值数据
}
// 表单元素失去焦点的回调函数
const toLook = (row: SaleAttr) => {
    const { baseSaleAttrId, saleAttrValue } = row;
    let newSaleAttrValue: SaleAttrValue = {
        baseSaleAttrId,//字段相同，省略赋值
        saleAttrValueName: (saleAttrValue as string),
    }
    // 非法情况判断
    if (saleAttrValue?.trim() == '') {
        ElMessage({
            type: 'error',
            message: '属性值不能为空'
        })
        return
    }
    let repeat = row.spuSaleAttrValueList.find(item => {
        return item.saleAttrValueName == saleAttrValue
    })
    if (repeat) {
        ElMessage({
            type: 'error',
            message: '属性值重复'
        })
    }

    row.spuSaleAttrValueList.push(newSaleAttrValue)
    row.flag = false;
}
// 保存按钮的回调函数
const save = async () => {
    // 照片墙数据
    SpuParams.value.spuImageList = imgList.value.map((item: any) => {
        return {
            imgName: item.name,
            imgUrl: (item.response && item.response.data) || item.url
        }
    })
    // 整理销售属性的数据
    SpuParams.value.spuSaleAttrList = saleAttr.value;
    // 发请求
    let result = await reqAddOrUpdateSpu(SpuParams.value);
    if (result.code == 200) {
        ElMessage({
            type: 'success',
            message: SpuParams.value.id ? '更新成功' : '添加成功'
        })
        $emit('changeScene',  { flag: 0, params: SpuParams.value.id?'update':'add' });//触发自定义事件，传递参数0
    } else {
        ElMessage({
            type: 'error',
            message: SpuParams.value.id ? '更新失败' : '添加失败'
        })
    }

}
// 对外暴露，使得父组件可以调用
defineExpose({ initHasSpuData, initAddSpu })
</script>

<style scoped></style>